<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;

class StoreApply extends Model
{
    use HasFactory, SoftDeletes;

    protected $table = 'ims_yz_store_apply';
    
    protected $fillable = [
        'uniacid',
        'uid',
        'username',
        'password',
        'realname',
        'mobile',
        'status',
        'information',
        'order_id',
        'validity',
        'salt',
        'pwd',
    ];

    protected $casts = [
        'information' => 'json',
        'created_at' => 'integer',
        'updated_at' => 'integer',
        'deleted_at' => 'integer'
    ];

    /**
     * 获取时间戳格式
     */
    public function getDateFormat()
    {
        return 'U'; // Unix timestamp
    }

    // 禁用 Laravel 的自动时间戳管理，因为数据库使用 int 类型
    public $timestamps = false;

    /**
     * 获取创建时间的 Carbon 实例
     */
    public function getCreatedAtAttribute($value)
    {
        return $value ? \Carbon\Carbon::createFromTimestamp($value) : null;
    }

    /**
     * 获取更新时间的 Carbon 实例
     */
    public function getUpdatedAtAttribute($value)
    {
        return $value ? \Carbon\Carbon::createFromTimestamp($value) : null;
    }

    /**
     * 获取删除时间的 Carbon 实例
     */
    public function getDeletedAtAttribute($value)
    {
        return $value ? \Carbon\Carbon::createFromTimestamp($value) : null;
    }

    const PAGE_SIZE = 20;
    const ADOPT = 1;
    const REJECT = -1;

    /**
     * 获取状态名称
     * @return string
     */
    public function getStatusNameAttribute()
    {
        switch ($this->status) {
            case 0:
                return '待审核';
            case 1:
                return '审核通过';
            case -1:
                return '驳回审核';
            default:
                return '未知状态';
        }
    }

    /**
     * 根据用户ID获取申请记录
     * @param $query
     * @param $uid
     * @return mixed
     */
    public function scopeByUid($query, $uid)
    {
        return $query->where('uid', $uid)->where('status', 0);
    }

    /**
     * 根据用户名获取申请记录
     * @param $query
     * @param $username
     * @return mixed
     */
    public function scopeByUsername($query, $username)
    {
        return $query->where('username', $username);
    }

    /**
     * 搜索范围
     * @param $query
     * @param $search
     * @return mixed
     */
    public function scopeSearch($query, $search)
    {
        if (isset($search['uid']) && $search['uid']) {
            $query->byUid($search['uid']);
        }

        if (isset($search['member']) && $search['member']) {
            $query->whereHas('member', function($memberBuilder) use($search) {
                $memberBuilder->where('realname', 'like', '%' . $search['member'] . '%')
                    ->orWhere('mobile', 'like', '%' . $search['member'] . '%')
                    ->orWhere('nickname', 'like', '%' . $search['member'] . '%');
            });
        }

        return $query;
    }

    /**
     * 关联用户模型
     * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
     */
    public function user()
    {
        return $this->belongsTo(User::class, 'uid', 'id');
    }

    /**
     * 关联会员模型
     * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
     */
    public function member()
    {
        return $this->belongsTo(Member::class, 'uid', 'uid');
    }

    /**
     * 关联订单模型
     * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
     */
    public function order()
    {
        return $this->belongsTo(Order::class, 'order_id', 'id');
    }

    /**
     * 关联省份
     * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
     */
    public function province()
    {
        $provinceId = $this->information['province_id'] ?? null;
        return $this->belongsTo(Address::class, null, 'id')->where('id', $provinceId);
    }

    /**
     * 关联城市
     * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
     */
    public function city()
    {
        $cityId = $this->information['city_id'] ?? null;
        return $this->belongsTo(Address::class, null, 'id')->where('id', $cityId);
    }

    /**
     * 关联区县
     * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
     */
    public function district()
    {
        $districtId = $this->information['district_id'] ?? null;
        return $this->belongsTo(Address::class, null, 'id')->where('id', $districtId);
    }

    /**
     * 获取省市地址访问器（只显示省市）
     */
    public function getFullAddressAttribute2()
    {
        $info = $this->information ?? [];
        
        $address = '';
        
        // 获取省份名称
        if (isset($info['province_id']) && $info['province_id']) {
            $province = Address::find($info['province_id']);
            if ($province) {
                $address .= $province->areaname;
            }
        }
        
        // 获取城市名称
        if (isset($info['city_id']) && $info['city_id']) {
            $city = Address::find($info['city_id']);
            if ($city) {
                $address .= ' ' . $city->areaname;
            }
        }
        
        return trim($address) ?: '地址信息不完整';
    }

    /**
     * 获取门店分类名称
     */
    public function getCategoryNameAttribute()
    {
        $information = $this->information;
        if (!$information || !is_array($information)) {
            return '';
        }

        $category_id = $information['category_id'] ?? null;
        if (!$category_id) {
            return '';
        }

        $category = \App\Models\StoreCategory::where('id', $category_id)->first();
        return $category ? $category->name : '';
    }
    
    /**
     * 获取省份ID访问器
     */
    public function getProvinceIdAttribute()
    {
        $info = $this->information ?? [];
        return $info['province_id'] ?? null;
    }
    
    /**
     * 获取城市ID访问器
     */
    public function getCityIdAttribute()
    {
        $info = $this->information ?? [];
        return $info['city_id'] ?? null;
    }
    
    /**
     * 获取区县ID访问器
     */
    public function getDistrictIdAttribute()
    {
        $info = $this->information ?? [];
        return $info['district_id'] ?? null;
    }

    /**
     * 获取门店申请列表
     * @param array $search
     * @return \Illuminate\Database\Eloquent\Builder
     */
    public static function getStoreApplyList($search = [])
    {
        return self::query()->search($search);
    }

    /**
     * 根据ID获取门店申请
     * @param int $id
     * @return \Illuminate\Database\Eloquent\Builder
     */
    public static function getStoreApplyById($id)
    {
        return self::query()
            ->with(['order' => function ($order) {
                $order->select(['id', 'order_sn']);
            }])
            ->where('id', $id);
    }

    /**
     * 根据用户ID获取门店申请
     * @param int $uid
     * @return \Illuminate\Database\Eloquent\Builder
     */
    public static function getStoreApplyByUid($uid)
    {
        return self::query()->byUid($uid);
    }

    /**
     * 根据用户名获取门店申请
     * @param string $username
     * @return \Illuminate\Database\Eloquent\Builder
     */
    public static function getStoreApplyByUsername($username)
    {
        return self::query()->select('id')->byUsername($username);
    }

    /**
     * 验证会员申请状态
     * @param int $uid
     * @throws \Exception
     */
    public static function verifyMemberHisApplyStatus($uid)
    {
        $apply_store = self::getStoreApplyByUid($uid)->first();
        if ($apply_store) {
            if ($apply_store->status == 0) {
                throw new \Exception('已提交申请,等待审核中');
            } else {
                throw new \Exception('已通过申请');
            }
        }
    }

    /**
     * 验证用户名唯一性
     * @param string $username
     * @throws \Exception
     */
    public static function verifyUsernameSole($username)
    {
        $apply_user = self::getStoreApplyByUsername($username)->first();
        if ($apply_user) {
            throw new \Exception('用户名重复');
        }
    }

    /**
     * 重写 save 方法，手动处理时间戳
     */
    public function save(array $options = [])
    {
        $now = time();
        
        if (!$this->exists) {
            $this->created_at = $now;
        }
        $this->updated_at = $now;
        
        return parent::save($options);
    }

    /**
     * 重写 delete 方法，手动处理软删除
     */
    public function delete()
    {
        if ($this->usesSoftDeletes()) {
            $this->deleted_at = time();
            return $this->save();
        }
        
        return parent::delete();
    }

    /**
     * 检查是否使用软删除
     */
    public function usesSoftDeletes()
    {
        return in_array(SoftDeletes::class, class_uses_recursive($this));
    }

    /**
     * 获取门店信息
     */
    public function getStoreInfoAttribute()
    {
        if (is_string($this->information)) {
            return json_decode($this->information, true);
        }
        return $this->information;
    }

    /**
     * 设置门店信息
     */
    public function setStoreInfoAttribute($value)
    {
        $this->attributes['information'] = is_array($value) ? json_encode($value) : $value;
    }

    /**
     * 检查是否可以申请
     */
    public static function canApply($uid)
    {
        return !self::where('uid', $uid)->whereIn('status', [0, 1])->exists();
    }

    /**
     * 获取申请状态
     */
    public static function getApplyStatus($uid)
    {
        // 检查是否已经是门店
        $store = Store::where('uid', $uid)->first();
        if ($store) {
            return [
                'status' => 3,
                'message' => '已经是门店,不能重复申请'
            ];
        }

        // 检查申请记录
        $apply = self::where('uid', $uid)->first();
        if ($apply) {
            if ($apply->status == 0) {
                return [
                    'status' => 2,
                    'message' => '已提交申请,等待审核',
                    'username' => $apply->username,
                    'password' => $apply->pwd
                ];
            } elseif ($apply->status == -1) {
                return [
                    'status' => -1,
                    'message' => '申请被驳回',
                    'last_info' => $apply->store_info
                ];
            }
        }

        return [
            'status' => 1,
            'message' => '可以进行申请'
        ];
    }

    /**
     * 获取营业执照图片
     */
    public function getAptitudeImagesAttribute()
    {
        $info = $this->store_info;
        if (isset($info['aptitude_imgs']) && is_array($info['aptitude_imgs'])) {
            return $info['aptitude_imgs'];
        }
        return [];
    }

    /**
     * 获取门店图片
     */
    public function getStoreImagesAttribute()
    {
        $info = $this->store_info;
        $images = [];
        
        if (isset($info['thumb']) && $info['thumb']) {
            $images[] = $info['thumb'];
        }
        if (isset($info['banner_thumb']) && $info['banner_thumb']) {
            $images[] = $info['banner_thumb'];
        }
        
        return $images;
    }

    /**
     * 获取营业时间
     */
    public function getBusinessHoursAttribute()
    {
        $info = $this->store_info;
        return [
            'start' => $info['business_hours_start'] ?? '',
            'end' => $info['business_hours_end'] ?? ''
        ];
    }

    /**
     * 获取完整地址
     */
    public function getFullAddressAttribute()
    {
        $info = $this->store_info;
        
        $fullAddress = '';
        if (isset($info['province_id']) && $info['province_id']) {
            $province = Address::where('id', $info['province_id'])->value('areaname');
            if ($province) $fullAddress .= $province;
        }
        if (isset($info['city_id']) && $info['city_id']) {
            $city = Address::where('id', $info['city_id'])->value('areaname');
            if ($city) $fullAddress .= $city;
        }
        if (isset($info['district_id']) && $info['district_id']) {
            $district = Address::where('id', $info['district_id'])->value('areaname');
            if ($district) $fullAddress .= $district;
        }
        if (isset($info['address']) && $info['address']) {
            $fullAddress .= $info['address'];
        }
        
        return $fullAddress;
    }

    /**
     * 检查营业执照是否上传
     */
    public function hasAptitudeImages()
    {
        return !empty($this->aptitude_images);
    }

    /**
     * 检查门店图片是否上传
     */
    public function hasStoreImages()
    {
        return !empty($this->store_images);
    }

    /**
     * 获取申请进度
     */
    public function getProgressAttribute()
    {
        $progress = 0;
        $info = $this->store_info;
        
        // 基本信息
        if ($this->username && $this->realname && $this->mobile) {
            $progress += 20;
        }
        
        // 门店信息
        if (isset($info['store_name']) && $info['store_name']) {
            $progress += 20;
        }
        if (isset($info['category_id']) && $info['category_id']) {
            $progress += 20;
        }
        if (isset($info['province_id']) && $info['province_id']) {
            $progress += 20;
        }
        if ($this->hasAptitudeImages()) {
            $progress += 20;
        }
        
        return $progress;
    }

    /**
     * 获取申请状态描述
     */
    public function getStatusDescriptionAttribute()
    {
        switch ($this->status) {
            case 0:
                return '您的申请已提交，正在审核中，请耐心等待';
            case 1:
                return '恭喜！您的申请已通过审核，可以开始使用门店功能';
            case -1:
                return '很抱歉，您的申请未通过审核，请检查信息后重新提交';
            default:
                return '申请状态异常，请联系客服';
        }
    }

    /**
     * information 字段写入访问器：在保存前统一规范化结构与类型
     */
    public function setInformationAttribute($value)
    {
        // 支持字符串或数组输入，并确保传入 normalizeInformation 的始终为数组
        $decoded = [];
        if (is_string($value)) {
            $tmp = $this->isJsonString($value) ? json_decode($value, true) : [];
            $decoded = is_array($tmp) ? $tmp : [];
        } elseif (is_array($value)) {
            $decoded = $value;
        }
    
        $normalized = $this->normalizeInformation($decoded);
        // 存储为 JSON 字符串，兼容现有表结构与读取逻辑
        $this->attributes['information'] = json_encode($normalized, JSON_UNESCAPED_UNICODE);
    }

    /**
     * information 字段读取访问器：统一返回规范化后的结构
     */
    public function getInformationAttribute($value)
    {
        // 统一返回规范化后的结构，容错处理字符串等非数组情况
        $tmp = $this->isJsonString($value) ? json_decode($value, true) : (is_array($value) ? $value : []);
        $decoded = is_array($tmp) ? $tmp : [];
        return $this->normalizeInformation($decoded);
    }

    /**
     * 统一规范化 information 字段
     */
    private function normalizeInformation(array $info): array
    {
        $padTime = function ($t) {
            if (!$t) return '';
            // 统一为 HH:mm
            if (preg_match('/^\d{1,2}:\d{1,2}$/', $t)) {
                [$h, $m] = explode(':', $t);
                $h = str_pad((string)intval($h), 2, '0', STR_PAD_LEFT);
                $m = str_pad((string)intval($m), 2, '0', STR_PAD_LEFT);
                return "$h:$m";
            }
            return $t;
        };

        $toInt = function ($v) {
            if ($v === '' || $v === null) return 0;
            return intval($v);
        };

        $toString = function ($v) {
            if ($v === null) return '';
            return is_scalar($v) ? (string)$v : '';
        };

        $toStringArray = function ($arr) {
            if (!is_array($arr)) return [];
            return array_values(array_filter(array_map(function ($x) {
                return is_scalar($x) ? trim((string)$x) : '';
            }, $arr), function ($x) { return $x !== ''; }));
        };

        // 统一字段
        $info['store_name'] = $toString($info['store_name'] ?? '');
        $info['thumb'] = $toString($info['thumb'] ?? '');

        // banner_thumb 统一为字符串（若传数组则取第一个非空）
        $banner = $info['banner_thumb'] ?? '';
        if (is_array($banner)) {
            $banner = $toString(array_values(array_filter($banner, function ($x) { return !empty($x); }))[0] ?? '');
        } else {
            $banner = $toString($banner);
        }
        $info['banner_thumb'] = $banner;

        $info['category_id'] = $toInt($info['category_id'] ?? 0);
        $info['province_id'] = $toInt($info['province_id'] ?? 0);
        $info['city_id'] = $toInt($info['city_id'] ?? 0);
        $info['district_id'] = $toInt($info['district_id'] ?? 0);
        $info['street_id'] = $toInt($info['street_id'] ?? 0);

        $info['address'] = $toString($info['address'] ?? '');
        $info['lng'] = $toString($info['lng'] ?? '');
        $info['lat'] = $toString($info['lat'] ?? '');

        $info['business_hours_start'] = $padTime($info['business_hours_start'] ?? '');
        $info['business_hours_end'] = $padTime($info['business_hours_end'] ?? '');

        $info['aptitude_imgs'] = $toStringArray($info['aptitude_imgs'] ?? []);
        $info['id_card_imgs'] = $toStringArray($info['id_card_imgs'] ?? []);
        $info['other_imgs'] = $toStringArray($info['other_imgs'] ?? []);

        $info['remark'] = $toString($info['remark'] ?? '');
        $info['store_introduce'] = $toString($info['store_introduce'] ?? '');
        // information_thumb 保持原样（为兼容现有字符串 HTML 处理流程）
        $info['information_thumb'] = $toString($info['information_thumb'] ?? '');

        $commission = $info['shop_commission'] ?? 0;
        $info['shop_commission'] = is_numeric($commission) ? (float)$commission : 0.0;

        $info['location_name'] = $toString($info['location_name'] ?? '');

        return $info;
    }

    /**
     * 判断是否为 JSON 字符串
     */
    private function isJsonString($value): bool
    {
        if (!is_string($value)) return false;
        json_decode($value);
        return (json_last_error() === JSON_ERROR_NONE);
    }
}